home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 3 / BBS in a box - Trilogy III.iso / Files / Prog / B-C / C++Source Code Fmtr Folder / Src / DataArea.cp < prev    next >
Encoding:
Text File  |  1992-04-27  |  6.2 KB  |  318 lines  |  [TEXT/MPS ]

  1. #ifndef __DATAAREA__
  2. #include "DataArea.h"
  3. #endif
  4.  
  5. #ifndef __ERRORS__
  6. #include <errors.h>
  7. #endif
  8.  
  9. #ifndef __OSUTILS__
  10. #include <osutils.h>
  11. #endif
  12.  
  13.  
  14. //µ DataArea::DataArea
  15. #pragma segment DataArea
  16. DataArea::DataArea()
  17.     : fHandle(0),
  18.       fSize(0),
  19.       fCursor(0),
  20.       fIncrement(0)
  21.     {
  22.     UseHeap(kAppHandleManager);
  23.     }
  24.  
  25.  
  26. //µ DataArea::IDataArea
  27. //
  28. #pragma segment DataArea
  29. OSErr DataArea::IDataArea(const DataArea *anArea)
  30. {
  31.     OSErr anErr = noErr;
  32.  
  33.     // Copy all fields
  34.     fHandle = anArea->fHandle;
  35.     fCursor = anArea->fCursor;
  36.     fSize = anArea->fSize;
  37.     fIncrement = anArea->fIncrement;
  38.     fHandleProc = anArea->fHandleProc;
  39.  
  40.     if (fHandle)
  41.         fHandleProc->Duplicate(anArea->fHandle, &fHandle, &anErr);
  42.  
  43.     return (anErr);
  44. }
  45.  
  46.  
  47. #pragma segment DataArea
  48. OSErr DataArea::IDataArea(size_t initialSize, size_t increment, Boolean useSize)
  49. {
  50.     OSErr anErr;
  51.  
  52.     fHandle = fHandleProc->NewHandle(initialSize, &anErr);
  53.     if (fHandle == 0)
  54.         return (anErr);
  55.  
  56.     fCursor = 0;
  57.     fSize = useSize ? initialSize : 0;
  58.     fIncrement = increment;
  59.  
  60.     return (noErr);
  61. }
  62.  
  63.  
  64. //µ DataArea::~DataArea
  65. //
  66. #pragma segment DataArea
  67. DataArea::~DataArea()
  68. {
  69.     OSErr anErr;
  70.  
  71.     if (fHandle)
  72.         fHandleProc->DisposHandle(fHandle, &anErr);
  73. }
  74.  
  75.  
  76. //µ DataArea::Assign
  77. #pragma segment DataArea
  78. OSErr DataArea::Assign(const DataArea *anArea)
  79. {
  80.     // If this is a "virgin" DataArea, use the intializer
  81.     if (fHandle == 0)
  82.         return (IDataArea(anArea));
  83.  
  84.     if (anArea->fHandle != 0) {
  85.         // Assure that there is room for the copy
  86.         size_t amtReqd = anArea->fSize;
  87.  
  88.         fCursor = 0;
  89.         if (Require(amtReqd) < amtReqd)
  90.             return (memFullErr);
  91.         BlockMove((Ptr)anArea->GetData(0), *fHandle, amtReqd);
  92.     }
  93.  
  94.     // Copy all fields
  95.     fCursor = anArea->fCursor;
  96.     fSize = anArea->fSize;
  97.     fIncrement = anArea->fIncrement;
  98.  
  99.     return (noErr);
  100. }
  101.  
  102.  
  103. //µ DataArea::Read
  104. #pragma segment DataArea
  105. size_t DataArea::Read(const void *aPtr, size_t aLen)
  106. {
  107.     size_t maxRead = fSize - fCursor;
  108.  
  109.     if (aLen > maxRead)
  110.         aLen = maxRead;
  111.  
  112.     BlockMove(*fHandle, (Ptr)aPtr, (Size)aLen);
  113.     return (aLen);
  114. }
  115.  
  116.  
  117. //µ DataArea::Write
  118. #pragma segment DataArea
  119. size_t DataArea::Write(void **aHndl)
  120. {
  121.     OSErr anErr;
  122.     size_t aHndlSize = fHandleProc->GetHandleSize(aHndl, &anErr);
  123.     size_t amtReqd = fCursor + aHndlSize;
  124.  
  125.     if (amtReqd > fSize)
  126.         if (Require(aHndlSize) < aHndlSize)
  127.             return (0);
  128.  
  129.     return (_Write(*aHndl, aHndlSize));
  130. }
  131.  
  132.  
  133. #pragma segment DataArea
  134. size_t DataArea::Write(const void *aPtr, size_t aLen)
  135. {
  136.     size_t amtReqd = fCursor + aLen;
  137.  
  138.     if (amtReqd > fSize)
  139.         if (Require(aLen) < aLen)
  140.             return (0);
  141.  
  142.     return (_Write(aPtr, aLen));
  143. }
  144.  
  145.  
  146. //µ DataArea::DecrCursor
  147. #pragma segment DataArea
  148. size_t DataArea::DecrCursor(size_t aDelta)
  149. {
  150.     if (aDelta > fCursor)
  151.         fCursor = 0;
  152.     else
  153.         fCursor -= aDelta;
  154.  
  155.     return (fCursor);
  156. }
  157.  
  158.  
  159. //µ DataArea::SetCursor
  160. #pragma segment DataArea
  161. size_t DataArea::SetCursor(size_t aCursor)
  162. {
  163.     fCursor = (aCursor <= fSize) ? aCursor : fSize;
  164.     return (fCursor);
  165. }
  166.  
  167.  
  168. //µ DataArea::Require
  169. #pragma segment DataArea
  170. size_t DataArea::Require(size_t amtReqd)
  171. {
  172.     OSErr anErr;
  173.     size_t sizeReqd = fCursor + amtReqd;
  174.  
  175.     if (sizeReqd > fSize) {
  176.         // Check if the handle is already large enough.  If it is, set the
  177.         // size to sizeReqd and return it.
  178.         if (sizeReqd <= fHandleProc->GetHandleSize(fHandle, &anErr)) {
  179.             fSize = sizeReqd;
  180.             return (fSize);
  181.         }
  182.  
  183.         // Expand the existing handle if possible.  First expand by the
  184.         // incremental amount if the amount requested is less than the
  185.         // increment.  If that fails or if the amount required is greater
  186.         // than the increment, expand by the amount required.  If the
  187.         // handle still could not be expanded, create a new handle and
  188.         // copy the data.
  189.         if (amtReqd <= fIncrement)
  190.             fHandleProc->SetHandleSize(fHandle, fCursor + fIncrement, &anErr);
  191.         if (amtReqd > fIncrement || anErr != noErr)
  192.             fHandleProc->SetHandleSize(fHandle, sizeReqd, &anErr);
  193.         if (anErr != noErr) {
  194.             // Oops.  Can't do it.  Create a new handle and copy data.  Again,
  195.             // do it in two steps: first the incremental amount then the minimum
  196.             // amount
  197.             void **aHndl = 0;
  198.  
  199.             if (amtReqd <= fIncrement)
  200.                 aHndl = fHandleProc->NewHandle(fCursor + fIncrement, &anErr);
  201.             if (aHndl == 0)
  202.                 aHndl = fHandleProc->NewHandle(sizeReqd, &anErr);
  203.  
  204.             if (aHndl == 0)
  205.                 return (0);
  206.  
  207.             // BlockMove does not move handles
  208.             BlockMove(*fHandle, *aHndl, fSize);
  209.             fHandleProc->DisposHandle(fHandle, &anErr);
  210.             fHandle = aHndl;
  211.         }
  212.  
  213.         // Update the size of this DataArea's handle
  214.         fSize = sizeReqd;
  215.     }
  216.  
  217.     // Return the amount available.
  218.     return (fSize - fCursor);
  219. }
  220.  
  221.  
  222. //µ DataArea::Delete
  223. #pragma segment DataArea
  224. void DataArea::Delete(size_t start, size_t end)
  225. {
  226.     if (fHandle) {
  227.         size_t chunkLength = end - start;
  228.         size_t tailLength = fSize - end;
  229.  
  230.         // Return if out of order or if zero length
  231.         if (start >= end || start > fSize)
  232.             return;
  233.  
  234.         // Adjust fCursor.  If before start, it doesn't move.  If between
  235.         // start and end, it moves to start.  Otherwise, it is beyond end
  236.         // and will be shifted down.
  237.         if (fCursor > start)
  238.             if (fCursor <= end)
  239.                 fCursor = start;
  240.             else
  241.                 fCursor -= chunkLength;
  242.  
  243.         // Copy the data.  fHandle[end .. fSize-1] is copied to fHandle[start]
  244.         BlockMove(GetData(end), GetData(start), (Size)tailLength);
  245.  
  246.         // Adjust the size
  247.         fSize -= chunkLength;
  248.     }
  249. }
  250.  
  251.  
  252. //µ DataArea::Truncate
  253. #pragma segment DataArea
  254. void DataArea::Truncate()
  255. {
  256.     OSErr anErr;
  257.  
  258.     if (fHandle)
  259.         fHandleProc->SetHandleSize(fHandle, (fSize = fCursor), &anErr);
  260. }
  261.  
  262.  
  263. //µ DataArea::AlignCursor
  264. #pragma segment DataArea
  265. size_t DataArea::AlignCursor(size_t alignment)
  266. {
  267.     size_t extraBytes = alignment - fCursor % alignment;
  268.  
  269.     // Assure the cursor is on an alignment boundary.
  270.     if (extraBytes != alignment)
  271.         if (Require(extraBytes) < extraBytes)
  272.             return (0);
  273.         else
  274.             fCursor += extraBytes;
  275.  
  276.     return (fCursor);
  277. }
  278.  
  279.  
  280. //µ DataArea::_Write
  281. #pragma segment DataArea
  282. size_t DataArea::_Write(const void *aPtr, size_t aLen)
  283. {
  284.     BlockMove((Ptr)aPtr, (Ptr)GetData(), (Size)aLen);
  285.     fCursor += aLen;
  286.     return (aLen);
  287. }
  288.  
  289.  
  290. //µ DataArea::HLock
  291. #pragma segment DataArea
  292. void DataArea::HLock()
  293. {
  294.     OSErr anErr;
  295.  
  296.     fHandleProc->HLock(fHandle, &anErr);
  297. }
  298.  
  299.  
  300. //µ DataArea::HUnlock
  301. #pragma segment DataArea
  302. void DataArea::HUnlock()
  303. {
  304.     OSErr anErr;
  305.  
  306.     fHandleProc->HUnlock(fHandle, &anErr);
  307. }
  308.  
  309.  
  310. //µ DataArea::MoveHHi
  311. #pragma segment DataArea
  312. void DataArea::MoveHHi()
  313. {
  314.     OSErr anErr;
  315.  
  316.     fHandleProc->MoveHHi(fHandle, &anErr);
  317. }
  318.